package com.message;


import com.constant.Constant;
import com.util.LogUtil;
import com.util.NetworkUtil;

import org.apache.mina.core.filterchain.DefaultIoFilterChainBuilder;
import org.apache.mina.core.future.ConnectFuture;
import org.apache.mina.core.service.IoHandlerAdapter;
import org.apache.mina.core.session.IoSession;
import org.apache.mina.filter.codec.ProtocolCodecFilter;
import org.apache.mina.transport.socket.SocketSessionConfig;
import org.apache.mina.transport.socket.nio.NioSocketConnector;

import java.net.InetSocketAddress;
import java.nio.charset.Charset;

/**
 * Created by Mars on 2017/9/21.
 */

public class UserClient {

    private int mPort;
    private String mIp;
    private int MAX_RECEIVE_BUFFER_SIZE = 1024 * 1024;
    public static final int MAX_READ_BUFFER_SIZE = 1024 * 1024;
    private int CONNECT_TIMEOUT = 30 * 1000;
    private DefaultIoFilterChainBuilder filterChain;

    private NioSocketConnector mSC = null;

    private IoSession mSession = null;
    private OperateState mOPState = OperateState.DISCONNECTED;

    // TODO: 2017/9/25 ip
//    private static String IP =

    public enum OperateState {
        DISCONNECTED, CONNECTING, CONNECTED,
        LOGGING_IN, LOGGED_IN
    }


    public UserClient(String ip, int port) {
        this.mIp = ip;
        this.mPort = port;
    }

    public void init(IoHandlerAdapter handler) {

        if (mSC == null) {
            mSC = new NioSocketConnector();

            SocketSessionConfig sessionConfig = mSC.getSessionConfig();

            sessionConfig.setMaxReadBufferSize(MAX_READ_BUFFER_SIZE);
            sessionConfig.setReceiveBufferSize(MAX_RECEIVE_BUFFER_SIZE);
            sessionConfig.setTcpNoDelay(true);
            sessionConfig.setUseReadOperation(true);

            filterChain = mSC.getFilterChain();
            if (!filterChain.contains("codec")) {
                filterChain.addLast("codec", new ProtocolCodecFilter(
                        new UserMessageProtocolCodecFactory()));
            }

            mSC.setConnectTimeoutMillis(CONNECT_TIMEOUT);

            if (!filterChain.contains("heartBeat")) {
                filterChain.addLast("heartBeat", new LotteryKeepAliveFilter());
            }

            mSC.setHandler(handler);

        }

    }

    public boolean connect() {
        synchronized (this) {
            LogUtil.e("connect");

            if (isConnected()) {
                return true;
            }

            if (!NetworkUtil.isNetworkAvailable()) {
                return false;
            }

//            ConnectFuture cf = null;
            try {
                mOPState = OperateState.CONNECTING;
                mSC.connect(new InetSocketAddress(Constant.IP, Constant.PORT));
            } catch (Exception e) {
                mOPState = OperateState.DISCONNECTED;
                return false;
            }

        }
        return false;
    }

    public boolean isStateConnected() {
        if (mOPState == OperateState.CONNECTED) {
            return true;
        }
        return false;
    }

    public boolean isStateConnecting() {
        if (mOPState == OperateState.CONNECTING) {
            return true;
        }
        return false;
    }

    public boolean isStateLoggingIn() {
        if (mOPState == OperateState.LOGGING_IN) {
            return true;
        }
        return false;
    }

    public boolean isStateLoggedIn() {
        if (mOPState == OperateState.LOGGED_IN) {
            return true;
        }
        return false;
    }

    public void disconnect() {
        synchronized (this) {
            LogUtil.e("disconnect");
            if (mSession != null) {
                try {
                    mSession.close(true).await(1500);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                mSession = null;
            }
            mOPState = OperateState.DISCONNECTED;
            // TODO: 2017/9/26 数据处理
//            HairdressingBean.getInstance().getUserEntity().setLogin(false);
        }
    }

    public boolean isConnected() {
        if (mSession != null && mSession.isConnected()) {
            return true;
        }
        return false;
    }

    /**
     * 发送请求
     *
     * @param packet
     * @return
     */
    public boolean sendRequest(MsgPacket packet) {
        if (packet == null) {
            return false;
        }
        // TODO: 2017/9/26 不同消息的处理
        mSession.write(packet);
        return true;
    }
}